package impl

import (
	"context"
	"errors"

	"gitee.com/hexug/devcloud/mcenter/apps/endpoint"
	"gitee.com/hexug/devcloud/mcenter/apps/role"
	"gitee.com/hexug/devcloud/mcenter/common/logger"
	"gitee.com/hexug/devcloud/mcenter/common/validate"
	"gitee.com/hexug/devcloud/mcenter/test/format"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo/options"
)

func (i *implServer) CreateRole(ctx context.Context, in *role.CreateRoleRequest) (*role.Role, error) {
	if err := validate.V().Struct(in); err != nil {
		return nil, err
	}
	newFeatures := []*role.Feature{}
	for _, f := range in.Features {
		if err := f.AddEndpointID(); err != nil {
			logger.L().Errorw(err.Error())
			continue
		}
		depr := endpoint.NewDetailEndpointRequest(f.EndpointId)
		_, err := i.endpoint.DetailEndpoint(ctx, depr)
		if err != nil {
			logger.L().Errorw(err.Error())
			logger.L().Errorf("%s 注册失败", format.FormatToJson(f))
			continue
		}
		newFeatures = append(newFeatures, f)
	}
	if len(newFeatures) <= 0 {
		return nil, errors.New("无合法角色注册")
	}
	in.Features = newFeatures
	drrbn := role.NewDetailRoleRequestByName(in.Name)
	r, err := i.DetailRole(ctx, drrbn)
	if err == nil {
		for _, f := range in.Features {
			if ok := r.HasFeatrueByEndpoint(f.EndpointId); !ok {
				r.Spec.AddFeature(f)
			}
		}
		filter := bson.M{"_id": r.Meta.Id}
		_, err := i.Col.UpdateOne(ctx, filter, bson.M{"$set": r})
		if err != nil {
			logger.L().Errorw(err.Error())
			return nil, err
		}
		return r, nil
	}
	logger.L().Infow(err.Error())
	r = role.NewRole(in)
	_, err = i.Col.InsertOne(ctx, r)
	if err != nil {
		return nil, err
	}
	return r, nil
}

func (i *implServer) QueryRole(ctx context.Context, in *role.QueryRoleRequest) (*role.RoleSet, error) {
	//校验数据
	if err := validate.V().Struct(in); err != nil {
		return nil, err
	}
	//防止过度获取
	if in.PageSize <= 0 || in.PageSize > 30 {
		in.PageSize = 5
	}
	if in.PageNumber <= 0 || in.PageNumber > 10 {
		in.PageNumber = 1
	}
	// fmt.Println(in)
	filter := bson.M{}
	//按创建时间倒排
	opt := options.Find().
		SetLimit(in.PageSize).
		SetSkip((in.PageNumber - 1) * in.PageSize).
		SetSort(bson.D{{Key: "created_at", Value: -1}}) //按创建时间倒序取出
	cursor, err := i.Col.Find(ctx, filter, opt)
	if err != nil {
		return nil, err
	}
	d := role.NewRoleSet()
	if err := cursor.All(ctx, &d.Items); err != nil {
		return nil, err
	}
	count, err := i.Col.CountDocuments(ctx, filter)
	if err != nil {
		return nil, err
	}
	d.Total = count
	return d, nil
}
func (i *implServer) DetailRole(ctx context.Context, in *role.DetailRoleRequest) (*role.Role, error) {
	//校验数据
	if err := validate.V().Struct(in); err != nil {
		return nil, err
	}
	var filter bson.M
	if in.DetailType == role.DESCRIBE_BY_ROLE_ID {
		filter = bson.M{"_id": in.Value}
	} else {
		filter = bson.M{"name": in.Value}
	}
	res := i.Col.FindOne(ctx, filter)
	if res.Err() != nil {
		return nil, res.Err()
	}
	r := role.New()
	if err := res.Decode(r); err != nil {
		return nil, err
	}
	return r, nil
}
